#ifndef _CQUEUE_H_
#define _CQUEUE_H_

/**
 * 循环队列
 * 实际buffer比申请多一个空间，主要为了方便空和满的判断
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <iostream>

template<typename T>
class CQueue{
    public:
        CQueue(){
        }
        /* 
         * tail的上一个为存储的最后一个空间，这样会一直有一个空间是空的,
         * 所以申请大小时候加1，这样可用空间就为外部传进来的大小
         */
        CQueue(size_t size){
            m_buf = new T[size+1];
            assert(m_buf!=NULL);
            m_size = size+1;
            m_head=0;
            m_tail=0;
        }
        bool empty(){return m_head==m_tail;}
        bool full(){return m_head==(m_tail+1)%m_size;}
        size_t size(){return m_size-1;}
        size_t length(){
            if(m_tail>=m_head){
                return m_tail-m_head;
            }
            else{
                return m_size-(m_head-m_tail);
            }
        };

        bool push(T t){
            if(full()){
                return false;
            }

            m_buf[m_tail] = t;
            m_tail = (m_tail+1)%m_size;
            return true;
        }

        T* pop(){
            if(empty()){
                return NULL;
            }
            T* t = &m_buf[m_head];
            m_head = (m_head+1)%m_size;
            return t;
        }
        
        T* get(){
            if(empty()){
                return NULL;
            }
            return &m_buf[m_head];
        }

        ~CQueue(){delete[] m_buf;}
    private:
        T*      m_buf;
        size_t  m_size;
        long    m_head;
        long    m_tail;
};

#endif
